﻿using FluorineFx.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;

namespace lxwmvc
{
    public class WeiXin_Fun
    {
        /// <summary>
        /// 获取缓存数据，如果缓存失败，通过文件捕获或者远程捕获
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="appid"></param>
        /// <param name="fun1"></param>
        /// <param name="fun2"></param>
        /// <returns></returns>
        public static T GetCacheValue<T>(string appid, Func<T, bool> fun1, Func<T> fun2)
        {
            //完整名称
            string key = typeof(T).FullName;

            //判断缓存中是否存在
            var v = WeiXin_Cache.Get<T>(key);
            var hascache = v != null;
            string path = HttpContext.Current.Server.MapPath(@"/weixin/fuwuhao/" + appid + "/" + key + ".json");

            if (!hascache)
            {
                //创建目录                
                CreateWeiXinDirectory(path);
                v = ReadFileString<T>(path);
            }

            //代表未过期
            if (v != null && !fun1(v))
            {
                if (!hascache) WeiXin_Cache.Insert(key, v,7200);
                return v;
            }

            v = fun2();
            //写入缓存和写入文件
            WeiXin_Cache.Insert(key, v,7200);
            CreateWeiXinDirectory(path);
            WriteFileString<T>(path, v);

            return v;
        }

        
        // 时间戳转为C#格式时间
        private DateTime StampToDateTime(string timeStamp)
        {
            DateTime dateTimeStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);

            return dateTimeStart.Add(toNow);
        }

        /// <summary>
        /// 把Unicode转换成功中文
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Unicode(string str)
        {
            string outStr = "";
            if (!string.IsNullOrEmpty(str))
            {
                string[] strlist = str.Replace("//", "").Split('u');
                try
                {
                    for (int i = 1; i < strlist.Length; i++)
                    {
                        //将unicode字符转为10进制整数，然后转为char中文字符  
                        outStr += (char)int.Parse(strlist[i], System.Globalization.NumberStyles.HexNumber);
                    }
                }
                catch (FormatException ex)
                {
                    outStr = ex.Message;
                }
            }
            return outStr;
        }

        // DateTime时间格式转换为Unix时间戳格式
        public static int DateTimeToStamp(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        public static T Get<T>(Dictionary<string, object> objValue, string key)
        {
            return objValue != null && objValue.ContainsKey(key) ? objValue[key].toT<T>() : default(T);
        }
        /// <summary>
        /// 截取两个字符串之间的数据
        /// </summary>
        /// <param name="objValue"></param>
        /// <param name="indexStr"></param>
        /// <param name="lastStr"></param>
        /// <param name="iDefault"></param>
        /// <param name="throwE"></param>
        /// <returns></returns>
        public static string SubString(string objValue, string indexStr = "", string lastStr = "", string iDefault = "", bool throwE = false)
        {
            try
            {
                int index = objValue.IndexOf(indexStr);
                if (lastStr != "" && index > -1)
                {
                    objValue = objValue.Remove(0, index);
                    index = objValue.IndexOf(indexStr);
                }
                int last = objValue.IndexOf(lastStr);
                last = last == 0 ? objValue.Length : last;
                if (index > -1 && last > -1)
                {
                    objValue = objValue.Substring(index + indexStr.Length, last - (index + indexStr.Length));
                    return objValue;
                }
                else
                {
                    return iDefault;
                }

            }
            catch (Exception error)
            {
                if (throwE) throw error;
                return iDefault;
            }
        }

        private static void CreateWeiXinDirectory(string path)
        {
            try
            {
                if (!Directory.Exists(Path.GetDirectoryName(path)))
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            catch { }
        }

        /// <summary>
        /// xml 2 json 字符串
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static string Xml2Json(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            JavaScriptObject obj = new JavaScriptObject();
            foreach (XmlNode node in doc.SelectSingleNode("xml").ChildNodes)
            {
                //获取内容
                obj[node.Name] = node.InnerText;
            }

            return JavaScriptConvert.SerializeObject(obj); 
        }

        

        public static string CreateNonceStr(int length = 16)
        {
            string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string str = "";
            Random rad = new Random();
            for (int i = 0; i < length; i++)
            {
                str += chars.Substring(rad.Next(0, chars.Length - 1), 1);
            }
            return str;
        }

        static void KeyValue2Xml(XmlElement node, KeyValuePair<string, object> Source)
        {
            object kValue = Source.Value;
            if (kValue.GetType() == typeof(Dictionary<string, object>))
            {
                foreach (KeyValuePair<string, object> item in kValue as Dictionary<string, object>)
                {
                    XmlElement element = node.OwnerDocument.CreateElement(item.Key);
                    KeyValue2Xml(element, item);
                    node.AppendChild(element);
                }
            }
            else if (kValue.GetType() == typeof(object[]))
            {
                object[] o = kValue as object[];
                for (int i = 0; i < o.Length; i++)
                {
                    XmlElement xitem = node.OwnerDocument.CreateElement("Item");
                    KeyValuePair<string, object> item = new KeyValuePair<string, object>("Item", o[i]);
                    KeyValue2Xml(xitem, item);
                    node.AppendChild(xitem);
                }

            }
            else
            {
                XmlText text = node.OwnerDocument.CreateTextNode(kValue.ToString());
                node.AppendChild(text);
            }
        }

        public readonly static object filesyn = new object[0]{};
        static T ReadFileString<T>(string path)
        {
            try
            {
                lock (filesyn)
                {
                    if (File.Exists(path))
                    {
                        using (StreamReader sr = new StreamReader(path))
                        {
                            return (T)JavaScriptConvert.DeserializeObject<T>(sr.ReadToEnd());
                        }
                    }
                    return default(T);
                }
            }
            catch (Exception e)
            {
                dataloger.fatal(e.Message, e);
                throw e;
            }
        }

        static void WriteFileString<T>(string path,T obj)
        {         
            try
            {
                lock (filesyn)
                {
                    try
                    {
                        //先删除文件
                        File.Delete(path);
                    }
                    catch { }
                    using (StreamWriter swWriter = new StreamWriter(path))
                    {
                        swWriter.WriteLine(JavaScriptConvert.SerializeObject(obj));
                    }
                }
            }
            catch (Exception e)
            {
                dataloger.fatal(e.Message, e);
                throw e;
            }
        }

        public static string GetUrl(string url, bool ispost = false, string bianma = "utf-8",string content = "")
        {
            try
            {
                Uri ourUri = new Uri(url);
                HttpWebRequest web = (HttpWebRequest)WebRequest.Create(ourUri);
                web.ReadWriteTimeout = 100;
                if (ispost)
                {
                    web.Method = "POST";
                }

                Encoding en = Encoding.GetEncoding(bianma);

                if (content.Length > 0)
                {
                    dataloger.info(content);
                    Stream myRequestStream = web.GetRequestStream();
                    var byt = en.GetBytes(content);
                    myRequestStream.Write(byt, 0, byt.Length);
                    myRequestStream.Close();
                }

                WebResponse myWebResponse = (HttpWebResponse)web.GetResponse();

                StreamReader stream = new StreamReader(myWebResponse.GetResponseStream(), en);

                return stream.ReadToEnd();
            }
            catch (Exception ex)
            {
                dataloger.fatal(ex.Message, ex);
                return "";
            }

        }


        public static string Agent(string agent)
        {

            string[] keywords = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };

            //排除 Windows 桌面系统
            if (!agent.Contains("Windows NT") || (agent.Contains("Windows NT") && agent.Contains("compatible; MSIE 9.0;")))
            {
                //排除 苹果桌面系统
                if (!agent.Contains("Windows NT") && !agent.Contains("Macintosh"))
                {
                    foreach (string item in keywords)
                    {
                        if (agent.Contains(item))
                        {
                            return item;
                        }
                    }
                }
            }

            return "";
        }
    }
}
